//
//  YLTextView.swift
//  YLTextView
//
//  Created by emma on 2023/8/18.
//

import UIKit

class YLTextView: UIView, UITextViewDelegate, UIGestureRecognizerDelegate {
    private var textView: UITextView!
    //是否点击返回失去响应
    var isReturnHidden: Bool = false {
        didSet{
            if isReturnHidden {
                self.textView.returnKeyType = .done
            }
        }
    }
    //占位标签
    private lazy var textViewPlaceholderLabel = UILabel()
    //字数标签
    private lazy var countLabel = UILabel()
    //限制输入个数，默认为999999，不限制输入
    private var limitWords: UInt = 999999
    private var tap: UITapGestureRecognizer!
    private var keyboardTextOrginY: CGFloat = 0.0
    private var beyondFrameY: CGFloat = 0.0
    private var adaptViewFrame: CGRect!
    private var adaptView: UIView!
    private var isEditing: Bool = false
    var text: String? {
        get {
            return textView.text
        }
    }
    
    //MARK: - 系统方法
    /// EBTextView 初始化方法
    convenience init(frame: CGRect, backgroundColor: UIColor? = nil, textColor: UIColor? = nil, font: UIFont? = nil, textAlignment: NSTextAlignment = .left, adaptView: UIView, text: String? = nil) {
        self.init(frame: frame)
        self.backgroundColor = backgroundColor
        
        textView = UITextView(frame: rect(0, 0, frame.width, frame.height))
        textView.text = text
        textView.textColor = textColor
        textView.font = font
        textView.textAlignment = textAlignment
        //textView.showsVerticalScrollIndicator = false
        textView.backgroundColor = .clear
        self.addSubview(textView)
        
        self.adaptView(adaptView, beyondY: 8)
        
        tap = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
        tap.delegate = self
        //键盘监听
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardFrame(aNotification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardFrame(aNotification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        //开始编辑
        NotificationCenter.default.addObserver(self, selector: #selector(addGesture), name: UITextView.textDidBeginEditingNotification, object: nil)
        //停止编辑
        NotificationCenter.default.addObserver(self, selector: #selector(hideKeyboard), name: UITextView.textDidEndEditingNotification, object: nil)
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
        MyLog("----------------\(self)销毁--------------------")
    }
    //设置placehoder topMargin用于调节和光标的中间对齐
    func setupPlaceholderLabel(placeholder: String?, placeholderColor: UIColor?, topMargin: CGFloat = 5) {
        let placeholderHeight = placeholder?.getHeight(textView.font!, frame.width) ?? 0
        textViewPlaceholderLabel.frame = rect(5, topMargin, frame.width-10, placeholderHeight)
        textViewPlaceholderLabel.text = placeholder
        textViewPlaceholderLabel.textColor = placeholderColor
        textViewPlaceholderLabel.textAlignment = textView.textAlignment
        textViewPlaceholderLabel.font = textView.font
        textViewPlaceholderLabel.numberOfLines = 0
        self.addSubview(textViewPlaceholderLabel)
        //将textView提到上面
        self.bringSubviewToFront(textView)
        
        textView.delegate = self
    }
    //设置文字个数
    func setupCountLabel(textColor: UIColor = .black, font: UIFont = UIFont.systemFont(ofSize: 17), textAlignment: NSTextAlignment = .left, limitWords: UInt, height: CGFloat) {
        textView.frame = rect(0, 0, frame.width, frame.height-height)
        
        countLabel.frame = rect(0, frame.height-height, frame.width, height)
        countLabel.textColor = textColor
        countLabel.font = font
        countLabel.textAlignment = textAlignment
        countLabel.text = "0/\(limitWords)"
        self.limitWords = limitWords
        self.addSubview(countLabel)
    }
    
    @objc func addGesture() {
        UIApplication.shared.keyWindow?.addGestureRecognizer(tap)
    }
    
    @objc func hideKeyboard() {
        textView.resignFirstResponder()
        UIApplication.shared.keyWindow?.removeGestureRecognizer(tap)
    }

    //MARK: 键盘显示响应事件
    @objc func handleKeyboardFrame(aNotification: NSNotification) {
        if (self.adaptView == nil) { return }
        if #available(iOS 9.0, *) {
            guard isEditing else { return }
            if aNotification.name == UIResponder.keyboardWillShowNotification {
                // 获取键盘高度
                let keyboardHeight: CGFloat = (aNotification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect).height
                //获取该控件在屏幕位置
                let window = UIApplication.shared.keyWindow
                let currentRect = self.convert(self.bounds, to: window!)
                //判断textView的高度和键盘高度之和是否大于屏幕高度 如何大于屏幕高度 只让textView部分上移 如果小于则全部显示
                //进入编辑的情况肯定是textView可见的
                if keyboardHeight+self.bounds.height+15 >= kScreenHeight {
                    MyLog(currentRect)
                    var frame = self.adaptViewFrame
                    frame?.origin.y -= (currentRect.origin.y-64-15)
                    UIView.animate(withDuration: 1) { [weak self] () in self?.adaptView.frame = frame! }
                }else {
                    if (keyboardTextOrginY < currentRect.origin.y) { keyboardTextOrginY = currentRect.origin.y }
                    let originY: CGFloat = keyboardTextOrginY + currentRect.size.height
                    
                    if kScreenHeight-originY <= keyboardHeight {
                        var changeY: CGFloat = keyboardHeight-(kScreenHeight-originY)
                        changeY += beyondFrameY
                        
                        var frame = self.adaptViewFrame
                        frame?.origin.y -= changeY
                        UIView.animate(withDuration: 1) { [weak self] () in self?.adaptView.frame = frame! }
                    }
                }
            }else if aNotification.name == UIResponder.keyboardWillHideNotification {
                keyboardTextOrginY = 0
                UIView.animate(withDuration: 1) { [weak self] () in self?.adaptView.frame = (self?.adaptViewFrame)! }
            }else {}
        } else {}
    }
    //MARK: 键盘自适应设置
    func adaptView(_ aview: UIView) {
        adaptView = aview
        adaptViewFrame = aview.frame
        beyondFrameY = 0.0
    }
    func adaptView(_ aview: UIView, beyondY: CGFloat) {
        adaptView = aview
        adaptViewFrame = aview.frame
        beyondFrameY = beyondY
    }
    //MARK: - 代理方法
    //MARK: 手势代理方法
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        guard let touchView = touch.view else { return false }
        if touchView.isKind(of: YLTextView.self) { return false }
        //点击的是否是子视图
        if touchView.isDescendant(of: self) { return false }
        return true
    }
    //MARK: UITextViewDelegate代理方法
    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        isEditing = true
        return true
    }
    func textViewDidEndEditing(_ textView: UITextView) {
        isEditing = false
    }
    func textViewDidChange(_ textView: UITextView) {
        textViewPlaceholderLabel.isHidden = textView.hasText
        countLabel.text = "\(textView.text.count)/\(limitWords)"
    }
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if text == "\n" && isReturnHidden == true { hideKeyboard() }
        //大于等于限制字数，而且不是删除键的时候不可以输入。
        if range.location+range.length >= limitWords && !(text as NSString).isEqual(to: "") { return false }
        return true
    }
}
